// MyAsyncSock.cpp : implementation file
//

#include "stdafx.h"
#include "MyAsyncSock.h"
#include "XDControlSystemDlg.h"

// MyAsyncSock

MyAsyncSock::MyAsyncSock(CDialog* pDlg)
{
	m_pDlg = pDlg;
	m_sendBuffer = "";   //for async send
	m_nBytesSent = 0;
	m_nBytesBufferSize = 0;
}

MyAsyncSock::~MyAsyncSock()
{
}

#if 0
BEGIN_MESSAGE_MAP(MyAsyncSock, CAsyncSocket)
	//{{AFX_MSG_MAP(MyAsyncSock)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()
#endif	// 0


void MyAsyncSock::OnAccept(int nErrorCode) 
{
	OutputDebugString(TEXT("MyAsyncSock::OnAccept\n"));

	CAsyncSocket::OnAccept(nErrorCode);
}

void MyAsyncSock::OnClose(int nErrorCode) 
{
	OutputDebugString(TEXT("MyAsyncSock::OnClose\n"));
	CAsyncSocket::OnClose(nErrorCode);
	delete this;
}

void MyAsyncSock::OnConnect(int nErrorCode) 
{
	OutputDebugString(TEXT("MyAsyncSock::OnConnect\n"));

	CAsyncSocket::OnConnect(nErrorCode);
}

void MyAsyncSock::OnOutOfBandData(int nErrorCode) 
{
	OutputDebugString(TEXT("MyAsyncSock::OnOutOfBandData\n"));

	CAsyncSocket::OnOutOfBandData(nErrorCode);
}

void MyAsyncSock::OnReceive(int nErrorCode) 
{
	OutputDebugString(TEXT("MyAsyncSock::OnReceive\n"));
	char buff[256];
	memset(buff,0,256);
	m_receiveBuffer = "";
	int nRead;
	Net receiveInformation;
	receiveInformation.ready = FALSE;
	nRead = ReceiveFrom(buff, 255, receiveInformation.ipAddr, receiveInformation.port); //make it smaller so we can experiment mulitple notifications
	switch (nRead)
	{
	case 0:
		Close();
		break;
	case SOCKET_ERROR:
		if (GetLastError() != WSAEWOULDBLOCK) 
		{
			if (GetLastError() != WSAEMSGSIZE)
			{
				TCHAR szError[256];
				wsprintf(szError, TEXT("OnReceive error: %d"), GetLastError());
				(( CXDControlSystemDlg*)m_pDlg)->printConnectError();
					return;
			}
			else
			{
				AfxMessageBox (TEXT("The datagram was too large and was truncated"));
				CString szTemp(buff);
				m_receiveBuffer += szTemp;
			}
		}
		break;

	default:
		if (nRead != SOCKET_ERROR && nRead != 0 )
		{
			TCHAR szError[256];
			wsprintf(szError, TEXT("OnReceive bytes: %d"), nRead);
			//AfxMessageBox (szError);

			buff[nRead] = 0; //terminate the string
			CString szTemp(buff);
			m_receiveBuffer += szTemp;
		}	
	}

	CAsyncSocket::OnReceive(nErrorCode);
	(( CXDControlSystemDlg*)m_pDlg)->pauseString(m_receiveBuffer,receiveInformation);
}

void MyAsyncSock::OnSend(int nErrorCode) 
{
	OutputDebugString(TEXT("MyAsyncSock::OnSend\n"));
	DoAsyncSendBuff();
	CAsyncSocket::OnSend(nErrorCode);
}

int MyAsyncSock::Receive(void* lpBuf, int nBufLen, int nFlags) 
{
	OutputDebugString(TEXT("MyAsyncSock::Receive\n"));

	return CAsyncSocket::Receive(lpBuf, nBufLen, nFlags);
}

int MyAsyncSock::Send(const void* lpBuf, int nBufLen, int nFlags) 
{
	// TODO: Add your specialized code here and/or call the base class
	OutputDebugString(TEXT("MyAsyncSock::Send\n"));

	return CAsyncSocket::Send(lpBuf, nBufLen, nFlags);
}

void MyAsyncSock::DoAsyncSendBuff()
{

	while (m_nBytesSent < m_nBytesBufferSize)  //m_nBytesBufferSize should be m_sendBuffer.GetLength() +1
	{
		int dwBytes;
		char buff[256];
		memset(buff,0,256);
		m_nBytesBufferSize = WideCharToMultiByte(CP_ACP, 0, m_sendBuffer, -1, buff, 255, NULL, NULL)+1;
		dwBytes = SendTo((LPCTSTR)buff + m_nBytesSent, m_nBytesBufferSize - m_nBytesSent, m_port, m_ip);

		if (dwBytes == SOCKET_ERROR)
		{
			if (GetLastError() == WSAEWOULDBLOCK) break;
			else
			{
				TCHAR szError[256];
				wsprintf(szError,TEXT( "Server Socket failed to send: %d"), GetLastError());
				Close();
				AfxMessageBox (szError);
				break;
			}
		}
		else
		{
			m_nBytesSent += dwBytes;
		}
	}

	if (m_nBytesSent == m_nBytesBufferSize)
	{
		m_nBytesSent = m_nBytesBufferSize = 0;
		m_sendBuffer = "";
	}
}
